#######################
###Miscellanious functions for setting up/running vdart search
#######################




def wFn(solPols,polSize,vocab,fields):
	"""weighting function for halfwaypoint calc"""
	from math import log
#the more weighted, the LESS likely the bit will become a 1
	bitweights=[1]*polSize
 	#create field ranges
	franges={}
	range1=0
#scale will cause large bins to more likely be 0
	scale={}
	for fieldIndex in fields:
		range2=range1+len([keys for keys in vocab if keys[0]==fieldIndex])-2
		franges[fields[fieldIndex]]=[range1,range2]
		scale[fields[fieldIndex]]=log(range2-range1+2,5)
		range1=range2+1			
	#weight appropriate to size of category
	for field in franges:
		startbit=franges[field][0]
		while startbit<=franges[field][1]:
			bitweights[startbit]*=scale[field]
			startbit+=1
	for policy in solPols:
		for a in range(polSize):
			if policy[a]==1:
				for field in franges:
					if franges[field][0]<=a<=franges[field][1]:
						myscale=scale[field]
				bitweights[a]+=myscale
	return bitweights





def loadDset(pathToFile):
	"""helper function to convert dataset csv into dataset dictionary, for search initialization"""
	import csv
	file=open(pathToFile)
	reader=csv.reader(file,delimiter=',')
	dset=[]
	for line in reader:
		toApend={'age':line[2],'race':line[3],'zip5':line[1],'sex':line[0]}
		dset.append(toApend)
	file.close()
	return dset





def extractPols(string):
	#for loading solution policies from file
	from policyEvaluation import PolicyString
	newStr=string.split(',')
	solPols=[]
	solPolStrings=[]
	for str in newStr:
		bits=[]
		for char in str:
			if char=='1':
				bits.append(True)
			if char=='0':
				bits.append(False)
		solPols.append(bits)
	for string in solPols:
		solPolStrings.append(PolicyString(string))
	return solPolStrings




def constraints(vocab,fields,vocablist,polSize):
	"""adds initial step to policy search that allows user to set \
specifications (ie: sex must be separate) to hold true in all policies"""
	import policyEvaluation
	genPolicy=policyEvaluation.PolicyString.mostGeneral(polSize)
	constraints=raw_input('Do you have any constraints?(Y/N) ')
	constraints=constraints.upper()
	if constraints=='Y':
		print('\n')*2
		F=raw_input('What field(Age,Sex,ZipCode,Race)? ')
		F=F.upper()
		#if user input string recognized as a field, turn bits of the corresponding ranges to 1
		if 'AGE' in F:
			print('\n')*2
			print('What age ranges must stay seperate? \'3-6\' means 3,4,5,6 will not be grouped')
			userin=raw_input('You can specify multiple ranges with \',\' (ex: 3-5,10-12,20-30): ')
			genPolicy=executeRanges(userin.split(','),'age',vocab,fields,vocablist,genPolicy)

		if 'SEX' in F:
			print('\n')*2
			userin=raw_input('Do you want sex (m/f) to stay specified?(Y/N) ')
			if userin.upper()=='Y':
				startIndex=0
				count=0
				ph=policyEvaluation.PolicyHandler(vocab,fields)	
				fieldindex=ph.fieldLookup['sex']
				while count!=fieldindex:
					startIndex+=len([i for i in vocab.keys() if i[0] == count])-1
					count+=1
				genPolicy[startIndex]=1

		if 'RACE' in F:
			print('\n')*2
			ph=policyEvaluation.PolicyHandler(vocab,fields)	
			fieldindex=ph.fieldLookup['race']
			print('What races must remain seperate?')
			print(vocablist[fieldindex])
			userin=raw_input('Specify range(s) (eg: \'0-2,3-4\') ')
			genPolicy=executeRanges(userin.split(','),'race',vocab,fields,vocablist,genPolicy)

		if 'ZIPCODE' in F:
			print('\n')*2
			userin=raw_input('What zipcodes must remain seperate? (eg: 31232-37235,30152-30064) ')
			genPolicy=executeRanges(userin.split(','),'zip5',vocab,fields,vocablist,genPolicy)
			

	return genPolicy	
		




def executeRanges(ranges,fieldname,vocab,fields,vocablist,genPolicy):
	"""helper function for constraints()"""
	import policyEvaluation
	#takes ranges, [3-5,10-12,18-20] etc and splits into integers to work with
	for r in ranges:
			values=r.split('-')
			minval=int(values[0])
			maxval=int(values[1])
			ph=policyEvaluation.PolicyHandler(vocab,fields)	
			fieldindex=ph.fieldLookup[fieldname]
			startIndex=0
			count=0
			while count!=fieldindex:
				startIndex+=len([i for i in vocab.keys() if i[0] == count])-1
				count+=1
			count=0
			if fieldname=='race':
				count=minval

			else:	
				while str(vocablist[fieldindex][count])!=str(minval):
					count+=1
			startIndex+=count
			for a in range(maxval-minval):
				genPolicy[startIndex]=True # separates all values in original range
				startIndex+=1
	return genPolicy

